﻿using System;
using System.Globalization;
using System.Text;

namespace TallComponents.Web.Pdf
{
   internal sealed class SelectionRectangle
   {
      /// <summary>
      /// Appends the rectangle as JSON to the string builder.
      /// </summary>
      /// <param name="sb">The string builder.</param>
      public void AppendAsJSON( StringBuilder sb )
      {
         sb.Append( "{" );
         sb.AppendFormat( CultureInfo.InvariantCulture, "Top:{0:0},Left:{1:0},Width:{2:0},Height:{3:0}", Top, Left, Width, Height );
         sb.Append( "}" );
      }

      /// <summary>
      /// Determines whether this rectangle is adjacent to another rectangle.
      /// </summary>
      /// <remarks>This method tries to determine whether two rectangles are near each other. If the 
      /// rectangles overlap or their distance is lower than <paramref name="tolerance"/> this method will
      /// return true.</remarks>
      /// <param name="other">The other rectangle.</param>
      /// <param name="tolerance">The tolerance.</param>
      /// <returns>
      /// 	<c>true</c> if the rectangles are adjacent; otherwise, <c>false</c>.
      /// </returns>
      public bool IsAdjacent( SelectionRectangle other, double tolerance )
      {
         return ( ( Right - other.Left > -tolerance ) && ( other.Right - Left > -tolerance ) ) && ( ( Top - other.Bottom > -tolerance ) && ( other.Top - Bottom > -tolerance ) );
      }

      /// <summary>
      /// Returns a rectangle that envelopes both this rectangle and the <paramref name="other"/> rectangle.
      /// </summary>
      /// <param name="other">The other rectangle.</param>
      /// <returns>A rectangle that envelopes both this rectangle and the <paramref name="other"/> rectangle.</returns>
      public SelectionRectangle Union( SelectionRectangle other )
      {
         return new SelectionRectangle
                {
                   Left = Math.Min( Left, other.Left ),
                   Right = Math.Max( Right, other.Right ),
                   Top = Math.Max( Top, other.Top ),
                   Bottom = Math.Min( Bottom, other.Bottom ),
                };
      }

      public double Left { get; set; }
      public double Top { get; set; }
      public double Right { get; set; }
      public double Bottom { get; set; }

      public double Height
      {
         get { return Top - Bottom; }
      }
      public double Width
      {
         get { return Right - Left; }
      }
   }
}
